1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 module android.ndk.dlext;
18 
19 import core.sys.posix.sys.types;
20 
21 import arsd.jni;
22 import android.ndk;
23 
24 extern (C):
25 nothrow:
26 @nogc:
27 
28 /* for off64_t */
29 
30 /**
31  * @addtogroup libdl Dynamic Linker
32  * @{
33  */
34 
35 /**
36  * \file
37  * Advanced dynamic library opening support. Most users will want to use
38  * the standard [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html)
39  * functionality in `<dlfcn.h>` instead.
40  */
41 
42 /** Bitfield definitions for `android_dlextinfo::flags`. */
43 enum
44 {
45     /**
46      * When set, the `reserved_addr` and `reserved_size` fields must point to an
47      * already-reserved region of address space which will be used to load the
48      * library if it fits.
49      *
50      * If the reserved region is not large enough, loading will fail.
51      */
52     ANDROID_DLEXT_RESERVED_ADDRESS = 0x1,
53 
54     /**
55      * Like `ANDROID_DLEXT_RESERVED_ADDRESS`, but if the reserved region is not large enough,
56      * the linker will choose an available address instead.
57      */
58     ANDROID_DLEXT_RESERVED_ADDRESS_HINT = 0x2,
59 
60     /**
61      * When set, write the GNU RELRO section of the mapped library to `relro_fd`
62      * after relocation has been performed, to allow it to be reused by another
63      * process loading the same library at the same address. This implies
64      * `ANDROID_DLEXT_USE_RELRO`.
65      *
66      * This is mainly useful for the system WebView implementation.
67      */
68     ANDROID_DLEXT_WRITE_RELRO = 0x4,
69 
70     /**
71      * When set, compare the GNU RELRO section of the mapped library to `relro_fd`
72      * after relocation has been performed, and replace any relocated pages that
73      * are identical with a version mapped from the file.
74      *
75      * This is mainly useful for the system WebView implementation.
76      */
77     ANDROID_DLEXT_USE_RELRO = 0x8,
78 
79     /**
80      * Use `library_fd` instead of opening the file by name.
81      * The filename parameter is still used to identify the library.
82      */
83     ANDROID_DLEXT_USE_LIBRARY_FD = 0x10,
84 
85     /**
86      * If opening a library using `library_fd` read it starting at `library_fd_offset`.
87      * This is mainly useful for loading a library stored within another file (such as uncompressed
88      * inside a ZIP archive).
89      * This flag is only valid when `ANDROID_DLEXT_USE_LIBRARY_FD` is set.
90      */
91     ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET = 0x20,
92 
93     /**
94      * When set, do not use `stat(2)` to check if the library has already been loaded.
95      *
96      * This flag allows forced loading of the library in the case when for some
97      * reason multiple ELF files share the same filename (because the already-loaded
98      * library has been removed and overwritten, for example).
99      *
100      * Note that if the library has the same `DT_SONAME` as an old one and some other
101      * library has the soname in its `DT_NEEDED` list, the first one will be used to resolve any
102      * dependencies.
103      */
104     ANDROID_DLEXT_FORCE_LOAD = 0x40,
105 
106     // Historically we had two other options for ART.
107     // They were last available in Android P.
108     // Reuse these bits last!
109     // ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80
110     // ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100
111 
112     /**
113      * This flag used to load library in a different namespace. The namespace is
114      * specified in `library_namespace`.
115      *
116      * This flag is for internal use only (since there is no NDK API for namespaces).
117      */
118     ANDROID_DLEXT_USE_NAMESPACE = 0x200,
119 
120     /**
121      * Instructs dlopen to apply `ANDROID_DLEXT_RESERVED_ADDRESS`,
122      * `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`, `ANDROID_DLEXT_WRITE_RELRO` and
123      * `ANDROID_DLEXT_USE_RELRO` to any libraries loaded as dependencies of the
124      * main library as well.
125      *
126      * This means that if the main library depends on one or more not-already-loaded libraries, they
127      * will be loaded consecutively into the region starting at `reserved_addr`, and `reserved_size`
128      * must be large enough to contain all of the libraries. The libraries will be loaded in the
129      * deterministic order constructed from the DT_NEEDED entries, rather than the more secure random
130      * order used by default.
131      *
132      * Each library's GNU RELRO sections will be written out to `relro_fd` in the same order they were
133      * loaded. This will mean that the resulting file is dependent on which of the libraries were
134      * already loaded, as only the newly loaded libraries will be included, not any already-loaded
135      * dependencies. The caller should ensure that the set of libraries newly loaded is consistent
136      * for this to be effective.
137      *
138      * This is mainly useful for the system WebView implementation.
139      */
140     ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE = 0x400,
141 
142     /** Mask of valid bits. */
143     ANDROID_DLEXT_VALID_FLAG_BITS = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_RESERVED_ADDRESS_HINT | ANDROID_DLEXT_WRITE_RELRO | ANDROID_DLEXT_USE_RELRO | ANDROID_DLEXT_USE_LIBRARY_FD | ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET | ANDROID_DLEXT_FORCE_LOAD | ANDROID_DLEXT_USE_NAMESPACE | ANDROID_DLEXT_RESERVED_ADDRESS_RECURSIVE
144 }
145 
146 struct android_namespace_t;
147 
148 /** Used to pass Android-specific arguments to `android_dlopen_ext`. */
149 struct android_dlextinfo
150 {
151     /** A bitmask of `ANDROID_DLEXT_` enum values. */
152     ulong flags;
153 
154     /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
155     void* reserved_addr;
156     /** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
157     size_t reserved_size;
158 
159     /** Used by `ANDROID_DLEXT_WRITE_RELRO` and `ANDROID_DLEXT_USE_RELRO`. */
160     int relro_fd;
161 
162     /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD`. */
163     int library_fd;
164     /** Used by `ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET` */
165     off64_t library_fd_offset;
166 
167     /** Used by `ANDROID_DLEXT_USE_NAMESPACE`. */
168     android_namespace_t* library_namespace;
169 }
170 
171 /**
172  * Opens the given library. The `__filename` and `__flags` arguments are
173  * the same as for [dlopen(3)](http://man7.org/linux/man-pages/man3/dlopen.3.html),
174  * with the Android-specific flags supplied via the `flags` member of `__info`.
175  *
176  * Available since API level 21.
177  */
178 
179 void* android_dlopen_ext (
180     const(char)* __filename,
181     int __flags,
182     const(android_dlextinfo)* __info);
183 /* __ANDROID_API__ >= 21 */
184 
185 /** @} */
186